using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

[System.Serializable]
public class FieldContainer
{
    // 存储字段名和数据的映射
    private readonly Dictionary<string, IFieldData> _fields = new Dictionary<string, IFieldData>();
    
    // 索引系统 - 用于高性能访问
    private readonly Dictionary<string, int> _fieldIndex = new Dictionary<string, int>();
    private IFieldData[] _fieldArray = Array.Empty<IFieldData>();
    private string[] _fieldNames = Array.Empty<string>();
    private bool _isDirty = true;
    
    // 字段数量
    public int FieldCount => _fields.Count;
    
    public void AddField(string name, IFieldData fieldData)
    {
        if (string.IsNullOrEmpty(name))
            throw new ArgumentException("Field name cannot be null or empty");
            
        _fields[name] = fieldData;
        _isDirty = true;
    }
    
    public bool RemoveField(string name)
    {
        if (_fields.Remove(name))
        {
            _isDirty = true;
            return true;
        }
        return false;
    }
    
    public bool ContainsField(string name) => _fields.ContainsKey(name);
    
    // 泛型获取方法 - 无装箱拆箱
    public bool TryGetField<T>(string name, out T value) where T : struct
    {
        if (_fields.TryGetValue(name, out var fieldData) && fieldData is FieldData<T> typedData)
        {
            value = typedData.Value;
            return true;
        }
        
        value = default;
        return false;
    }
    
    // 泛型设置方法 - 无装箱拆箱
    public bool TrySetField<T>(string name, T value) where T : struct
    {
        if (_fields.TryGetValue(name, out var fieldData) && fieldData is FieldData<T> typedData)
        {
            typedData.Value = value;
            return true;
        }
        return false;
    }
    
    // 获取字段数据（可能涉及装箱，慎用）
    public IFieldData GetFieldData(string name)
    {
        return _fields.TryGetValue(name, out var fieldData) ? fieldData : null;
    }
    
    // 高频访问优化方法 - 通过索引访问
    public IFieldData GetFieldByIndex(int index)
    {
        if (_isDirty) RebuildIndex();
        return index >= 0 && index < _fieldArray.Length ? _fieldArray[index] : null;
    }
    
    public string GetFieldNameByIndex(int index)
    {
        if (_isDirty) RebuildIndex();
        return index >= 0 && index < _fieldNames.Length ? _fieldNames[index] : null;
    }
    
    public int GetFieldIndex(string name)
    {
        if (_isDirty) RebuildIndex();
        return _fieldIndex.TryGetValue(name, out int index) ? index : -1;
    }
    
    // 补全的 RebuildIndex 方法
    private void RebuildIndex()
    {
        if (!_isDirty) return;
        
        int count = _fields.Count;
        
        // 重新初始化数组
        if (_fieldArray.Length != count)
        {
            _fieldArray = new IFieldData[count];
            _fieldNames = new string[count];
        }
        
        _fieldIndex.Clear();
        
        int index = 0;
        foreach (var kvp in _fields)
        {
            _fieldNames[index] = kvp.Key;
            _fieldArray[index] = kvp.Value;
            _fieldIndex[kvp.Key] = index;
            index++;
        }
        
        _isDirty = false;
    }
    
    // 批量操作优化
    public void MarkDirty() => _isDirty = true;
    
    // 枚举所有字段（避免在热路径中使用）
    public IEnumerable<KeyValuePair<string, IFieldData>> GetAllFields()
    {
        return _fields;
    }
    
    // 获取所有字段名
    public string[] GetAllFieldNames()
    {
        if (_isDirty) RebuildIndex();
        return _fieldNames.ToArray(); // 返回副本
    }
    
    public void Clear()
    {
        _fields.Clear();
        _isDirty = true;
    }
    
    public void Dispose()
    {
        _fields.Clear();
        _fieldIndex.Clear();
        _fieldArray = Array.Empty<IFieldData>();
        _fieldNames = Array.Empty<string>();
    }
    
    // 性能监控方法
    public void LogMemoryUsage()
    {
        long memory = 0;
        foreach (var field in _fields.Values)
        {
            // 估算内存使用
            memory += System.GC.GetTotalMemory(false);
        }
        Debug.Log($"FieldContainer memory usage: {memory} bytes, Fields: {_fields.Count}");
    }
}